<?php

namespace app\api\model;

use app\api\model\Common;
use think\Validate;
use app\common\Content;
use think\Request;
use app\common\extract\Word;
use app\api\model\SystemConfig;
use think\Db;

class LiveSpeech1 extends Common
{
    protected $name = 'meeting_live_speech';
    protected $tranStatus = [0 => '实时转写中', 1 => '非实时转写中', 2 => '转写完成', 3 => '文件错误'];
    protected $_content;
    protected function initialize()
    {
        //需要调用`Model`的`initialize`方法
        parent::initialize();
        //TODO:自定义的初始化
        $this->_content = new Content();
    }

    public function equipment()
    {
        return $this->hasOne('Equipment', 'equipmentid', 'did');
    }

    public function speechs()
    {
        return $this->hasMany('Speech', 'meeting_id', 'id');
    }
    //关联单一附表
    public function oneSpeech()
    {
        return $this->hasOne('Speech', 'meeting_id', 'id');
    }
    public function convert()
    {
        return $this->hasMany('SpeechVadFile', 'sid', 'id');
    }
    public function mconvert()
    {
        return $this->hasMany('Convert', 'lid', 'id');
    }
    //关联liveDetail模型
    public function liveDetail()
    {
        return $this->hasOne('LiveDetail', 'lid', 'id');
    }
    //领域
    public function scenes()
    {
        return $this->belongsTo('Scenes', 'sid');
    }
    /**
     * 文件列表
     */
    public function getList($map, $limit, $page)
    {
        try {
            $filter = [
                'a.id', 'a.filename as formatname', 'a.did as device_id', 'u.username as user_name', 'a.start_time', 'a.create_time',
                'a.end_time', 'a.transition_state as lvsr_status', 'a.notes', 'a.is_manual', 'a.size', 'a.meeting_tag as meeting_id', 'a.seconds',
                'e.serial as serial', 'a.update_time as update_t', 'e.title as device_name', 'e.type', 'e.connection', 'a.sid', 'a.title'
            ];
            $_union = $this->alias('a')->join('equipment e', 'a.did = e.equipmentid', 'LEFT')->join('admin_user u', 'a.uid = u.id');
            $list = $_union->where($map)->limit($limit)->page($page)->order('a.update_time desc')->field($filter)->select();

            $count = $this->alias('a')->join('equipment e', 'a.did = e.equipmentid', 'LEFT')->join('admin_user u', 'a.uid = u.id')
                ->where($map)->count();
            $system_config_model = new SystemConfig;
            $offline_num = $system_config_model->get(['name' => 'OFFLINE_NUM'])->value;

            foreach ($list as &$value) {
                $value['device_type'] = $value['type'] ?: 3;
                $value['device_name'] = $value['device_name'] ?: "--";
                $value['size'] = $value['size'] ? trans_byte($value['size']) : '--';
                //添加一个体验判断，如果盒子连接状态是关闭，切之前正在转写中，则返回断开状态
                if ($value['lvsr_status'] == 4 && $value['type'] == 1 && $value['connection'] == 2) {
                    $value['lvsr_status'] = '7';
                }

                switch ($value['lvsr_status']) {
                    case 1:
                        if ($value['seconds']) {
                            $cost_time = number_format((time() - $value['update_t']) / ($value['seconds'] / $offline_num) * 100, 0, '', '');
                            $time = $cost_time < 100 ? $cost_time  : 99;
                        } else {
                            $time = 0;
                        }
                        $value['progress'] = intval($time);
                        break;
                    case 2:
                        $value['progress'] = 100;
                        break;
                    case 5:
                        $value['progress'] = 100;
                        break;
                    default:
                        $value['progress'] = 0;
                        break;
                }

                if ($value['start_time'] && $value['end_time']) {
                    $value['consume_time'] = gmstrftime('%H:%M:%S', $value['end_time'] - $value['start_time']);
                } else {
                    $value['consume_time'] = "--:--:--";
                }
                if ($value['seconds']) {
                    $value['audioLength'] = gmstrftime('%H:%M:%S', (float) $value['seconds']);
                }
                if ($value['title']) {
                    $value['formatname'] = $value['title'];
                }
            }

            $tranStatus = [
                0 => '确认中',
                1 => '非实时中',
                2 => '非实时完成',
                3 => '文件错误',
                4 => '实时中',
                5 => '实时完成',
                6 => '文件上传中',
                7 => '连接断开',
            ];
            $type_arr = [1 => '智能终端', 2 => '录音笔', 3 => '电脑', 4 => '绘声字幕'];
            $scene_list = Db::name('scenes')->select();
            $scenes = array();
            foreach ($scene_list as $scene) {
                $scenes[$scene['id']] = $scene['name'];
            }
            return [
                'list' => $list,
                'total' => $count,
                'totalPage' => ceil($count / $limit),
                'type' => $type_arr,
                'status' => $tranStatus,
                'scenes' => $scenes,
            ];
        } catch (\Exception $e) {
            //$this->error = $e->getMessage();
            $this->error = '请求失败';
            return false;
        }
    }

    /**
     * 删除列表
     */
    public function getdelList($map, $limit, $page)
    {
        try {
            $filter = ['id as sfrid', 'uid as user_id', 'filename', 'update_time as create_time'];
            //获取删除属性为1的speech表中的数组
            $lists = $this->where($map)->field($filter)->limit($limit)->page($page)->order('create_time desc')->select();
            foreach ($lists as &$val) {
                //$val['create_time'] = date("Y-m-d H:i:s", $val['create_time']);
                $val['sid'] = $val['sfrid'];
            }
            $total = $this->where(['is_delete' => 1])->count();
            $result = [
                'list' => $lists,
                'total' => $total,
                'total_page' => ceil($total / $limit)
            ];
            return $result;
        } catch (\Exception $e) {
            //$this->error = $e->getMessage();
            $this->error = '删除失败';
            return false;
        }
    }

    /**
     * 获取文件详情
     */
    public function getDetail($id, $piecewise = false)
    {
        $data = $this->get(['id' => $id]);
        if (!$data) {
            $this->error = '暂无此数据';
            return false;
        }
        $result['audio_time'] = gmstrftime('%H:%M:%S', $data->seconds ? $data->seconds : 0);
        //$result['audio'] = ($data->is_manual == 2 && Model('Equipment')->where(['equipmentid' => $data->did])->find()['type'] != 2) ?  Request::instance()->domain() . "/huisheng_api/data/speech3/" . $data->uid . "/" . $data->formatname . ".mp3" : Request::instance()->domain() . "/huisheng_api/data/speech3/" . $data->uid . "/" . pathinfo($data->filename)['filename'] . ".mp3";
        //$result['audio'] = $data->is_manual == 2 ?  Request::instance()->domain() . "/huisheng_api/data/speech3/" . $data->uid . "/" . $data->formatname . ".mp3" : Request::instance()->domain() . "/huisheng_api/data/speech3/" . $data->uid . "/" . pathinfo($data->filename)['filename'] . ".mp3";
        $result['audio'] = Request::instance()->domain() . config("huisheng.mp3") . DS . $data->uid . "/" . $data->formatname . ".mp3";
        $result['json'] = str_replace(".mp3", ".json", $result['audio']);
        $result['lvsr_data_edit_state'] = $data->editor ? "已编辑" : "未编辑";
        $result['lvsr_status'] = $this->tranStatus[$data->transition_state];
        $result['status'] = $data->transition_state;
        $result['create_time'] =  $data->create_time;
        $result['end_time'] = date("Y-m-d H:i:s", $data->end_time);
        $result['size'] = $data->size;
        $result['speech_id'] = $data->id;
        $result['filename'] = $data->title ?: $data->filename;
        $result['meetingId'] = $data->meeting_tag;
        $result['serial'] = $data->equipment->serial;
        $result['did'] = $data->did;
        $result['is_manual'] = $data->is_manual;
        $result['lvsr_txt'] = '';
        $lvsr_data = $data->editor ? json_decode($data->editor, true)['list'] : json_decode($data->transfer, true)['list'];
        $result['lvsr_data'] = array();
        $result['notes'] = $data->notes;
        $roles = Db::name('separate_to_file')->where('fid', $id)->select();
        $result['is_role'] = 1;
        foreach ($roles as $role) {
            if (!$role['status']) {
                $result['is_role'] = 2;
                break;
            }
        }
        $result['scene'] = $data->scenes['name'];
        //var_dump($data->scenes);die;
        if ($lvsr_data) {
            foreach ($lvsr_data as $value) {
                // if ($value['txt'] != '') {
                //     array_push($result['lvsr_data'], $value);
                // }
                array_push($result['lvsr_data'], $value);
            }
        }
        if ($piecewise) {
            $result['lvsr_data'] = $this->_content->setJson($result['lvsr_data'])->paragraphToTen()->getArr();
        }
        $result['tranStatus'] = [
            0 => '确认中',
            1 => '非实时中',
            2 => '非实时完成',
            3 => '文件错误',
            4 => '实时中',
            5 => '实时完成',
            6 => '文件上传中',
        ];
        return $result;
    }

    /**
     * 获取非实时转写结果纯文本
     */
    public function getTransferResult($id, $type = 1)
    {
        try {
            $content = $this->get($id);
            if (!$content) {
                $this->error = '暂无此数据';
                return false;
            }
            switch ($type) {
                case 1:
                    $data = $content->speechs()->where('lvsr_status', 3)->field('lvsr_data')->order('filename asc')->select();
                    foreach ($data as $val) {
                        foreach (json_decode($val->lvsr_data, true)['list'] as $sentence) {
                            $this->_content->push($sentence['txt'], (explode("-", $sentence['time'])[1] - explode("-", $sentence['time'])[0]) * config('FRAME'));
                        }
                    }
                    break;
                case 2:
                    $data = Db::name('meeting_convert')->where('lid', $id)->order('sorting asc')->select();
                    foreach ($data as $val) {
                        $this->_content->push($val['editor'] ? $val['editor'] : $val['transfer'], $val['pcmtime'], $sc = $val['subsection']);
                    }
                    break;
                case 3:
                    $data = json_decode($content->transfer, true)['list'];
                    return $this->_content->setJson($data)->paragraphToTen()->getArr();
                case 4:
                    $data = json_decode($content->editor, true)['list'];
                    $this->_content->setJson($data);
                    break;
                default:
                    $this->error = '类型错误';
                    return false;
            }
            //如果返回空 则返回空数组
            if (!$this->_content->paragraph()->getArr()) {
                return [];
            }
            return $this->_content->paragraph()->getArr();
        } catch (\Exception $e) {
            $this->error = '查询错误';
            return false;
        }
    }

    /**
     * 组合去语气词和原始文档功能
     */
    public function combination(int $mood_type, int $is_initial, int $sensitive_type, int $paragraph = 1)
    {
        try {
            //选择编辑结果还是转写结果
            if (!$is_initial && $this->editor) {
                $this->_content->setJson(json_decode($this->editor, true)['list']);
            } else {
                $this->_content->setJson(json_decode($this->transfer, true)['list']);
            }
            //选择添加语气词
            if ($mood_type) {
                $this->_content->modal();
            }
            //选择去除敏感词
            if ($sensitive_type) {
                $this->_content->sensitive();
            }
            //选择分段方式
            if ($paragraph) {
                $this->_content->paragraphToTen();
            } else {
                $this->_content->paragraph();
            }
            return $this->_content->getArr();
        } catch (\Exception $e) {
            throw new \Exception($e->getMessage());
        }
    }

    /**
     * 去除语气词
     */
    public function getModalOff($content)
    {
        $result = $this->_content->setJson(json_decode($content, true)['list'])->modal()->paragraph()->getArr();
        if (!$result) {
            $this->error = '去除语气词失败';
            return false;
        }
        return $result;
    }

    /**
     * 获取下载文件
     */
    public function getDownloadFile($id, $type, $param)
    {
        $data = $this->get($id);
        switch ($type) {
            case 'mp3':
                $result = config('huisheng.upload_mp3_path') . DS . $data->uid . DS . $data->formatname . ".mp3";
                break;
            case 'doc':
                $param['data'] = $this->_content->setJson($data->editor ? json_decode($data->editor, true)['list'] : json_decode($data->transfer, true)['list'])->paragraphToTen()->deword();
                $param['data'] = str_replace('{$rep}', "<w:br />", $param['data']);
                $result = (new Word())->template2File($data->formatname, $param);
                break;
            case 'docx':
                $param['data'] = $this->_content->setJson($data->editor ? json_decode($data->editor, true)['list'] : json_decode($data->transfer, true)['list'])->paragraph()->deword_role();
                $param['data'] = str_replace('{$rep}', "<w:br />", $param['data']);
                $result = (new Word())->template2File($data->formatname, $param);
                break;
            case 'srt':
                $param = $this->_content->setJson($data->editor ? json_decode($data->editor, true)['list'] : json_decode($data->transfer, true)['list'])->srt();
                $result = config('huisheng.word_result') . $data->formatname . ".srt";
                file_put_contents($result, $param);
                break;
            default:
                $this->error = '匹配类型错误';
                $result = false;
        }
        return $result;
    }

    /**
     * 下载文件
     */
    public function downloaTxt($data)
    {
        try {
            $args = ['title' => '', 'time' => '', 'address' => '', 'host' => '', 'record' => '', 'name' => '', 'remark' => '', 'data' => ''];
            $data = $this->_content->setJson($data)->deword();
            $args['data'] = str_replace('{$rep}', "<w:br />", $data);
            $result = (new Word())->template2File($this->filename, $args);
            return $result;
        } catch (\Exception $e) {
            throw new \Exception($e->getMessage());
        }
    }

    /**
     * 新版下载文件，文件的处理不在后端做，在前端生成
     */
    public function downloadTxtNew($data){
        try {
            $args = ['title' => '', 'time' => '', 'address' => '', 'host' => '', 'record' => '', 'name' => '', 'remark' => '', 'data' => $data];
            $result = (new Word())->template2File($this->filename, $args);
            return $result;
        } catch (\Exception $e) {
            throw new \Exception($e->getMessage());
        }
    }

    /**
     * 批量删除文件
     */
    public function deletDatas($ids = [])
    {
        try {
            $this->where($this->getPk(), 'in', $ids)->update(['is_delete' => 1, 'update_time' => time()]);
            return true;
        } catch (\Exception $e) {
            $this->error = '删除失败';
            return false;
        }
    }

    /**
     * 获取摘要
     */
    public function getAbstract($id)
    {
        $data = $this->get($id);
        $result = $this->_content->setJson($data->editor ? json_decode($data->editor, true)['list'] : json_decode($data->transfer, true)['list'])->modal()->abstract();
        return $result;
    }

    /**
     * 返回转写文件剩余时间
     */
    public function remainingTimeDisplay()
    {
    }

    /**
     * 创建文件
     */
    public function createFileData($param)
    {
        // 验证
        $validate = validate($this->name);
        if (!$validate->check($param)) {
            throw new \Exception($validate->getError());
            $this->error = $validate->getError();
            return false;
        }
        try {
            $this->data($param)->allowField(true)->save();
            return $this->id;
        } catch (\Exception $e) {
            throw new \Exception($e->getMessage());
            $this->error = '添加失败';
            return false;
        }
    }

    /**
     * 获取转写结束的标准文件列表
     *
     * @return void
     * @Description
     * @example
     * @author Kelike
     * @since
     */
    public function getEndSpeechList()
    {
        $map = [
            'transition_state' => ['in', [0, 1]],
            'is_delete' => 0,
            'is_manual' => 1,
        ];
        $return = array();
        $meetings = $this->where($map)->field('id,transition_state')->select();
        while (null != ($meeting = array_pop($meetings))) {
            if ($meeting->transition_state == 0) {
                //最后上传的文件的创建时间 和现在比超过 最大间隔 1小时
                $last_speech = $meeting->speechs()->order('filename desc')->limit(1)->find();
                //如果没有文件 就继续
                if (empty($last_speech) || (time() - $last_speech->create_time) < config('huisheng.upload_file_max_interval')) {
                    continue;
                }
            } else if ($meeting->transition_state == 1) {
                //文件转写数量 和 上传数量相同
                $speech_detail = Db::name('live_speech_detail')->where('lid', $meeting->id)->find();
                if (count($meeting->speechs) !== $speech_detail['vad_count']) {
                    continue;
                }
            }
            //循环检查 转写数据的完整性
            foreach ($meeting->speechs as $speech) {

                if ($speech->lvsr_status == 3) {
                    //如果没有转写结果 则转写失败
                    if (!$speech->lvsr_data) {
                        $meeting->transition_state = 3;
                        $meeting->save();
                        continue 2;
                    }
                } else {
                    continue 2;
                }
            }
            $return[] = $meeting->id;
        }
        return $return;
    }

    public function editSpeechtoReTransfer($id)
    {
        $data = $this->get($id);
        if (!$data) {
            $this->error = '未查找到转写数据';
            return false;
        }
        if ($data->is_manual == 1) {
            $data->transition_state = 1;
            $data->update_time = time();
            $data->save();
        }
        return true;
    }

    /**
     * [createData 新建]
     * @linchuangbin
     * @DateTime  2017-02-10T21:19:06+0800
     * @param     array                    $param [description]
     * @return    [array]                         [description]
     */
    public function createData($param)
    {

        //验证
        $validate = validate($this->name);
        if (!$validate->check($param)) {
            $this->error = $validate->getError();
            return false;
        }
        try {
            $this->data($param)->allowField(true)->save();
            return true;
        } catch (\Exception $e) {
            $this->error = '添加失败';
            return false;
        }
    }
}
